from typing import List
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession

from crud.document import document_tag as tag_crud
from schemas.document.document_tag import (
    DocumentTagCreate, DocumentTagUpdate, DocumentTagResponse,
    DocumentTagWithCount
)
from db.session import get_db
from log import log_api, log_error

router = APIRouter(
    prefix="/document-tags",
    tags=["document-tags"]
)


@router.get("/", response_model=List[DocumentTagWithCount])
async def get_all_tags(
    include_count: bool = Query(True, description="是否包含文档数量统计"),
    db: AsyncSession = Depends(get_db)
):
    """
    获取所有文档标签
    
    - **include_count**: 是否包含每个标签关联的文档数量
    """
    log_api("获取所有文档标签", module="router.document_tag")
    try:
        if include_count:
            tags_with_count = await tag_crud.get_tags_with_document_count(db)
            return [
                DocumentTagWithCount(
                    id=tag.id,
                    name=tag.name,
                    color=tag.color,
                    created_at=tag.created_at,
                    document_count=count
                )
                for tag, count in tags_with_count
            ]
        else:
            tags = await tag_crud.get_all_tags(db)
            return [
                DocumentTagWithCount(
                    id=tag.id,
                    name=tag.name,
                    color=tag.color,
                    created_at=tag.created_at,
                    document_count=0
                )
                for tag in tags
            ]
    except Exception as e:
        log_error(f"获取标签列表失败: {str(e)}", exc_info=True, module="router.document_tag")
        raise HTTPException(status_code=500, detail="获取标签列表失败")


@router.post("/", response_model=DocumentTagResponse)
async def create_tag(
    tag: DocumentTagCreate,
    db: AsyncSession = Depends(get_db)
):
    """
    创建新的文档标签
    
    - **name**: 标签名称（必填，唯一）
    - **color**: 标签颜色（可选，默认#007bff）
    """
    log_api(f"创建文档标签: {tag.name}", module="router.document_tag")
    try:
        # 检查标签名称是否已存在
        existing_tag = await tag_crud.get_tag_by_name(db, tag.name)
        if existing_tag:
            raise HTTPException(status_code=400, detail="标签名称已存在")
        
        db_tag = await tag_crud.create_tag(db, tag)
        return DocumentTagResponse.model_validate(db_tag)
    except HTTPException:
        raise
    except Exception as e:
        log_error(f"创建标签失败: {str(e)}", exc_info=True, module="router.document_tag")
        raise HTTPException(status_code=500, detail="创建标签失败")


@router.put("/{tag_id}", response_model=DocumentTagResponse)
async def update_tag(
    tag_id: UUID,
    tag: DocumentTagUpdate,
    db: AsyncSession = Depends(get_db)
):
    """
    更新文档标签信息
    
    - **tag_id**: 要更新的标签ID
    - 其他字段均为可选，只更新提供的字段
    """
    log_api(f"更新文档标签: {tag_id}", module="router.document_tag")
    try:
        # 如果要更新名称，检查是否与其他标签重复
        if tag.name:
            existing_tag = await tag_crud.get_tag_by_name(db, tag.name)
            if existing_tag and existing_tag.id != tag_id:
                raise HTTPException(status_code=400, detail="标签名称已存在")
        
        updated_tag = await tag_crud.update_tag(db, tag_id, tag)
        if not updated_tag:
            raise HTTPException(status_code=404, detail="标签不存在")
        
        return DocumentTagResponse.model_validate(updated_tag)
    except HTTPException:
        raise
    except Exception as e:
        log_error(f"更新标签失败: {str(e)}", exc_info=True, module="router.document_tag")
        raise HTTPException(status_code=500, detail="更新标签失败")


@router.delete("/{tag_id}")
async def delete_tag(
    tag_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    删除文档标签
    
    - **tag_id**: 要删除的标签ID
    
    注意：删除标签会自动解除与所有文档的关联关系
    """
    log_api(f"删除文档标签: {tag_id}", module="router.document_tag")
    try:
        success = await tag_crud.delete_tag(db, tag_id)
        if not success:
            raise HTTPException(status_code=404, detail="标签不存在")
        
        return {"message": "标签删除成功"}
    except HTTPException:
        raise
    except Exception as e:
        log_error(f"删除标签失败: {str(e)}", exc_info=True, module="router.document_tag")
        raise HTTPException(status_code=500, detail="删除标签失败")


@router.get("/search", response_model=List[DocumentTagResponse])
async def search_tags(
    search_term: str = Query(..., description="搜索关键词", min_length=1),
    limit: int = Query(10, description="返回数量限制", ge=1, le=50),
    db: AsyncSession = Depends(get_db)
):
    """
    搜索文档标签
    
    - **search_term**: 搜索关键词（在标签名称中搜索）
    - **limit**: 返回结果数量限制
    """
    log_api(f"搜索文档标签: {search_term}", module="router.document_tag")
    try:
        tags = await tag_crud.search_tags_by_name(db, search_term)
        limited_tags = tags[:limit]
        return [DocumentTagResponse.model_validate(tag) for tag in limited_tags]
    except Exception as e:
        log_error(f"搜索标签失败: {str(e)}", exc_info=True, module="router.document_tag")
        raise HTTPException(status_code=500, detail="搜索标签失败")


@router.get("/popular", response_model=List[DocumentTagWithCount])
async def get_popular_tags(
    limit: int = Query(10, description="返回数量限制", ge=1, le=50),
    db: AsyncSession = Depends(get_db)
):
    """
    获取最受欢迎的标签
    
    按关联文档数量排序返回最受欢迎的标签
    
    - **limit**: 返回结果数量限制
    """
    log_api(f"获取热门标签，限制 {limit} 个", module="router.document_tag")
    try:
        popular_tags = await tag_crud.get_popular_tags(db, limit)
        return [
            DocumentTagWithCount(
                id=tag.id,
                name=tag.name,
                color=tag.color,
                created_at=tag.created_at,
                document_count=count
            )
            for tag, count in popular_tags
        ]
    except Exception as e:
        log_error(f"获取热门标签失败: {str(e)}", exc_info=True, module="router.document_tag")
        raise HTTPException(status_code=500, detail="获取热门标签失败")
